﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Live;
using System.Collections.Generic;
using System.IO;
using System.Threading;
using System.IO.IsolatedStorage;
using System.Diagnostics;
using OnlineVideos.Services.FileStoreService;
using System.ServiceModel;

namespace Common.Services
{

    public class RestoreData
    {
        LiveConnectClient lcc = null;
        private string skyDriveFolderName = "";
        AutoResetEvent sync = new AutoResetEvent(false);
        private string skyDriveFolderID = string.Empty;
        private string _FileName = string.Empty;
        string UserId = "";
        IsolatedStorageFile isoStore = IsolatedStorageFile.GetUserStoreForApplication();
        IsolatedStorageFileStream isostream;
        int restoreFileCount = 0;
        int restoreFileCompletedCount = 0;
        int restoreFileNotCompletedCount = 0;
        Button restore = null;

        public void GetFolderId(string skyDriveFolderNa, Microsoft.Live.LiveConnectClient client, string Id, Button btnRestore)
        {
            try
            {
                restore = btnRestore;
                lcc = client;
                skyDriveFolderName = skyDriveFolderNa;
                UserId = Id;
                client.GetCompleted += new EventHandler<LiveOperationCompletedEventArgs>(GetCompleted);
                client.GetAsync("me/skydrive/files?filter=folders,albums");
            }
            catch (Exception ex)
            {
                MessageBox.Show("Some data not restored, please try again later");
                Exception exnew = new Exception("Exception in restore Method In Settings file\n\n" + ex.Message + " \n\n Stack Trace \n" + ex.StackTrace);
                throw exnew;
            }
        }

        void GetCompleted(object sender, LiveOperationCompletedEventArgs e)
        {
            try
            {
                lcc.GetCompleted -= this.GetCompleted;
                if (e.Error == null)
                {
                    Dictionary<string, object> folderData = (Dictionary<string, object>)e.Result;
                    List<object> folders = (List<object>)folderData["data"];

                    foreach (object item in folders)
                    {
                        Dictionary<string, object> folder = (Dictionary<string, object>)item;
                        if (folder["name"].ToString() == skyDriveFolderName)
                            skyDriveFolderID = folder["id"].ToString();
                    }

                    if (skyDriveFolderID == string.Empty)
                    {
                        Service1Client service = new Service1Client();
                        service.GetUserFileNamesAsync("activitytracker", UserId, "userdata");
                        service.GetUserFileNamesCompleted += new EventHandler<GetUserFileNamesCompletedEventArgs>(service_GetUserFileNamesCompleted);
                    }
                    else
                        DownloadFiles(skyDriveFolderID);
                }
                else
                {
                    MessageBox.Show(e.Error.Message);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("Some data not restored, please try again later");
                Exception exnew = new Exception("Exception in restore Method In Settings file\n\n" + ex.Message + " \n\n Stack Trace \n" + ex.StackTrace);
                throw exnew;
            }
        }

        private void DownloadFiles(string skyDriveFolderID)
        {
            try
            {
                lcc.DownloadCompleted += new EventHandler<LiveDownloadCompletedEventArgs>(client_DownloadCompleted);
                lcc.DownloadAsync(skyDriveFolderID + "/files");
            }
            catch (Exception ex)
            {
                MessageBox.Show("Some data not restored, please try again later");
                Exception exnew = new Exception("Exception in restore Method In Settings file\n\n" + ex.Message + " \n\n Stack Trace \n" + ex.StackTrace);
                throw exnew;
            }
        }

        void client_DownloadCompleted(object sender, LiveDownloadCompletedEventArgs e)
        {
            try
            {
                lcc.DownloadCompleted -= this.client_DownloadCompleted;
                if (e.Error == null)
                {
                    GetDocumentId(e.Result);

                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("Some data not restored, please try again later");
                Exception exnew = new Exception("Exception in restore Method In Settings file\n\n" + ex.Message + " \n\n Stack Trace \n" + ex.StackTrace);
                throw exnew;
            }
        }

        private void GetDocumentId(Stream stream)
        {
            try
            {
                StreamReader sr = new StreamReader(stream);
                string data = sr.ReadToEnd();

                string[] parts = data.Split(',');
                List<string> dat = new List<string>(parts);

                ThreadPool.QueueUserWorkItem(func =>
                {
                    foreach (var item in dat)
                    {
                        if (item.Contains("upload_location"))
                        {
                            string[] id = item.Split('/');
                            Downloaddata(id[4].ToString()); //you need to call this on a separate thread or it will lock the ui thread.                       
                        }
                        else if (item.Contains("name"))
                        {
                            if (item.Contains(".txt"))
                            {
                                char[] delimiters = new char[] { '\r', '\n', ':', '.', '\t' };
                                string[] name = item.Split(delimiters,
                         StringSplitOptions.RemoveEmptyEntries);
                                //  string[] filename = item.Split('.',RemoveHandler);
                                SaveFileName(name[2].ToString());
                                // SettingsHelper.Save("IsoFileName", name[2].ToString());
                            }
                        }

                    }
                    Deployment.Current.Dispatcher.BeginInvoke(() =>
                    {
                        restore.IsEnabled = true;
                        MessageBox.Show("All data successfully restored");
                    });    //your button click method is now also asynchronous
                });
            }
            catch (Exception ex)
            {
                MessageBox.Show("Some data not restored, please try again later");
                Exception exnew = new Exception("Exception in restore Method In Settings file\n\n" + ex.Message + " \n\n Stack Trace \n" + ex.StackTrace);
                throw exnew;
            }
        }

        private void SaveFileName(string p)
        {
            try
            {
                string file = p.Replace("\"", "");
                _FileName = file.Trim() + ".xml";
            }
            catch (Exception ex)
            {
                MessageBox.Show("Some data not restored, please try again later");
                Exception exnew = new Exception("Exception in restore Method In Settings file\n\n" + ex.Message + " \n\n Stack Trace \n" + ex.StackTrace);
                throw exnew;
            }
        }

        private void Downloaddata(string p)
        {
            try
            {
                lcc.DownloadCompleted += new EventHandler<LiveDownloadCompletedEventArgs>(DownloadCompleted);
                lcc.DownloadAsync(p + "/content");
                sync.WaitOne();
            }
            catch (Exception ex)
            {
                MessageBox.Show("Some data not restored, please try again later");
                Exception exnew = new Exception("Exception in restore Method In Settings file\n\n" + ex.Message + " \n\n Stack Trace \n" + ex.StackTrace);
                throw exnew;
            }
        }
        void DownloadCompleted(object sender, LiveDownloadCompletedEventArgs e)
        {
            try
            {
                lcc.DownloadCompleted -= this.DownloadCompleted;

                DownLoadFileToIsotore(e.Result);
                sync.Set();
            }
            catch (Exception ex)
            {
                MessageBox.Show("Some data not restored, please try again later");
                Exception exnew = new Exception("Exception in restore Method In Settings file\n\n" + ex.Message + " \n\n Stack Trace \n" + ex.StackTrace);
                throw exnew;
            }

        }
        private void DownLoadFileToIsotore(Stream stream)
        {
            try
            {
                IsolatedStorageFile isoStore = IsolatedStorageFile.GetUserStoreForApplication();
                IsolatedStorageFileStream isostream;

                string filename = "ActivityTracker/" + _FileName;
                if (isoStore.FileExists(filename))
                    isoStore.DeleteFile(filename);
                byte[] MyStream = StreamToByteArray(stream);
                if (!isoStore.FileExists(filename))
                {
                    isostream = new IsolatedStorageFileStream(filename, FileMode.Create, isoStore);
                    int read = MyStream.Length;
                    isostream.Write(MyStream, 0, read);
                    isostream.Close();
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("Some data not restored, please try again later");
                Exception exnew = new Exception("Exception in restore Method In Settings file\n\n" + ex.Message + " \n\n Stack Trace \n" + ex.StackTrace);
                throw exnew;
            }
        }
        static byte[] StreamToByteArray(Stream inputStream)
        {
            if (!inputStream.CanRead)
            {
                throw new ArgumentException();
            }

            // This is optional
            if (inputStream.CanSeek)
            {
                inputStream.Seek(0, SeekOrigin.Begin);
            }

            byte[] output = new byte[inputStream.Length];
            int bytesRead = inputStream.Read(output, 0, output.Length);
            Debug.Assert(bytesRead == output.Length, "Bytes read from stream matches stream length");
            return output;
        }

        void service_GetUserFileNamesCompleted(object sender, GetUserFileNamesCompletedEventArgs e)
        {
            try
            {
                if (e.Error == null)
                {
                    if (e.Result != null && e.Result.Count > 0)
                    {
                        restoreFileCount = e.Result.Count;
                        foreach (string file in e.Result)
                        {
                            string isofilename = "";
                            Service1Client service1 = new Service1Client();
                            service1.RestoreUserDataAsync("activitytracker", UserId, "userdata", file, isofilename);
                            service1.RestoreUserDataCompleted += new EventHandler<RestoreUserDataCompletedEventArgs>(service1_RestoreUserDataCompleted);
                        }
                    }
                    else
                    {
                        MessageBox.Show("There is no data for the specified User or Data doesn't exist");
                    }
                }
                else if (e.Error is FaultException)
                {

                    MessageBox.Show("Failed to restore data, Please try again later");
                    FaultException fault = e.Error as FaultException;
                    //Exception.SaveExceptionInLocalStorage(e.Error.Message);
                }
            }
            catch (Exception ex)
            {
                string mess = "Exception in service_GetUserFileNamesCompleted Method In Settings file.\n\n" + ex.Message + "\n\n Stack Trace:- " + ex.StackTrace;
                //  Exceptions.SaveOrSendExceptions(mess, ex.Data);
            }
        }

        void service1_RestoreUserDataCompleted(object sender, RestoreUserDataCompletedEventArgs e)
        {
            try
            {
                if (e.Error == null)
                    restoreFileCompletedCount++;
                else
                    restoreFileNotCompletedCount++;

                if (e.Result != null)
                {
                    if (!isoStore.DirectoryExists("ActivityTracker"))
                        isoStore.CreateDirectory("ActivityTracker");

                    byte[] MyStream = e.Result;
                    string filename = "ActivityTracker/" + e.restorefilename;

                    if (isoStore.FileExists(filename))
                        isoStore.DeleteFile(filename);

                    if (!isoStore.FileExists(filename))
                    {
                        isostream = new IsolatedStorageFileStream(filename, FileMode.Create, isoStore);
                        int read = MyStream.Length;
                        isostream.Write(MyStream, 0, read);
                        isostream.Close();
                    }
                }
                if (restoreFileCount == restoreFileCompletedCount + restoreFileNotCompletedCount)
                {
                    string str = "";
                    if (restoreFileNotCompletedCount > 0)
                        str = "Some data not restored, please try again later";
                    else
                        str = "All data successfully restored";
                    MessageBox.Show(str);

                }
            }
            catch (Exception ex)
            {
                string mess = "Exception in service1_RestoreUserDataCompleted Method In Settings file.\n\n" + ex.Message + "\n\n Stack Trace:- " + ex.StackTrace;
                //  Exceptions.SaveOrSendExceptions(mess, ex.Data);
            }
        }



      
    }
}
